import os.path
import typing

from yangke.ebsilon.graphicsview import YkGraphicsItem, Port
from yangke.ebsilon.constant.constant import Pressure, Temperature, Enthalpy, MassFlow, Power, Length, Area, One, Other, \
    VolumeFlow, SpecificVolume
from yangke.performance.iapws97 import get_h_by_pt, IAPWS97
from yangke.common.QtImporter import QRectF, QLineF, QPointF, Qt, QPoint, QPainter, QWidget, QStyleOptionGraphicsItem, \
    QIcon

SpecificationValues = {
    "流体状态参数(总，滞止)": [
        ["压降", "DP", "", Pressure("MPa")],
        ["介质温度", "T", "", Temperature("℃"), "tacit"],
        ["介质焓", "H", "", Enthalpy("kJ/kg"), "tacit"],
        ["介质比容", "V", "", SpecificVolume("m^3/kg")],
        ["质量流量", "M", "", MassFlow("t/h")],
        ["体积流量", "VM", "", VolumeFlow("m^3/h")],
    ],
    "管道结构参数": [
        ["结构类型", "TYPE", ["热压弯管", "锻造弯管", "焊接弯管"], None],
        ["公称直径", "DN", "", Length("m")],
        ["管道截面积", "A", "", Area("m^2"), "tacit"],
        ["管道内径", "DI", "", Length("m")],
    ],
    "管道材质": [
        ["材质", "MAT", ["冷拔钢管", "普通钢管/熟铁管", "涂沥青铸铁管", "镀锌铸铁管", "其他"], None],  # 材质决定等值粗糙度
        ["等值粗糙度", "EPSILON", "", Length("mm"), "func:等值粗糙度(MAT)"]  # 该参数的值由函数 等值粗糙度(MAT)决定。如果制定了材质，则该值不可编辑
    ]
}  # 不能有逗号
Result = {
    "Total": [
        ["雷诺数", "Re", "", One()],
        ["介质运动粘度", "Gamma", "", Other("m^2/s")],
        ["介质动力粘度", "mu", "", Other("Pa·s")]
    ]
}


class Item(YkGraphicsItem):
    def __init__(self):
        """

        """
        super(Item, self).__init__()
        self.width = 80
        self.height = 80
        self.EBS_ID = 10093  # ebsilon软件中的组件id
        self.NAME = "自定义计算组件"
        self.EBS_NAME = ""  # ebsilon中的组件名
        self.EBS_TYPE = "Calculator"  # ebsilon帮助文件中组件所属的组

        # Ebsilon组件面板中的Ports页信息
        self.ports = {
            1: Port(idx=1, point=QPointF(-40, 0), type1="Inlet", description="Inlet port"),
            2: Port(idx=2, point=QPointF(40, 0), type1="Outlet", description="Outlet port")
        }
        self.SpecificationValues = SpecificationValues
        self.Result = Result

    def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem,
              widget: typing.Optional[QWidget] = ...) -> None:
        """
        绘制组件图形

        :param painter:
        :param option:
        :param widget:
        :return:
        """
        # 绘制组件实体
        self.pen[0].setColor(Qt.red)
        self.pen[0].setWidth(4)
        painter.setPen(self.pen[0])
        painter.drawLine(QLineF(QPointF(-30, 0), QPointF(-40, 0)))
        painter.drawLine(QLineF(QPointF(-30, 20), QPointF(-40, 20)))
        painter.drawLine(QLineF(QPointF(-30, -20), QPointF(-40, -20)))
        painter.drawLine(QLineF(QPointF(30, 0), QPointF(40, 0)))
        painter.drawLine(QLineF(QPointF(30, 20), QPointF(40, 20)))
        painter.drawLine(QLineF(QPointF(30, -20), QPointF(40, -20)))
        painter.drawLine(QLineF(QPointF(0, -30), QPointF(0, -40)))
        painter.drawLine(QLineF(QPointF(20, -30), QPointF(20, -40)))
        painter.drawLine(QLineF(QPointF(-20, -30), QPointF(-20, -40)))
        painter.drawLine(QLineF(QPointF(0, 30), QPointF(0, 40)))
        painter.drawLine(QLineF(QPointF(-20, 30), QPointF(-20, 40)))
        painter.drawLine(QLineF(QPointF(20, 30), QPointF(20, 40)))

        self.pen[1].setColor(Qt.black)
        self.pen[1].setWidth(1)
        painter.setPen(self.pen[1])
        self.brush[1].setColor(Qt.yellow)
        painter.setBrush(self.brush[1])
        painter.drawPolygon([QPoint(-30, -30), QPoint(30, -30), QPoint(30, 30), QPoint(-30, 30)], Qt.OddEvenFill)  # 三角形

        super(Item, self).paint(painter, option, widget)  # 必须最后调用

    def calculate(self, step=0):
        DI = self.get("DI")
        if DI is None:
            area = self.get("A")
            if area is None:
                return f"未设置管道直径！---0"  # ---0表示立即退出计算循环

        p1 = self.get("P1")
        t1 = self.get("T1")
        h1 = self.get("H1")
        m1 = self.get("M1")
        p2 = self.get("P2")
        t2 = self.get("T2")
        h2 = self.get("H2")
        m2 = self.get("M2")
        if p1 is not None:  # 端口1的压力与端口2的压力相同
            self.set("P2", p1)
        elif p2 is not None:
            self.set("P1", p2)
        if t1 is not None:
            self.set("T2", t1)
        elif t2 is not None:
            self.set("T1", t2)
        if m1 is not None:
            self.set("M2", m1)
            self.set("M", m1)
        elif m2 is not None:
            self.set("M1", m2)
            self.set("M", m2)
        try:
            water = IAPWS97(T=t1, P=p1, H=h1)
            self.set("V", water.v)
            self.set("DP", self.get("P1") - self.get("P2"))

        except:
            return "not finished"

        return "done"


def 等值粗糙度(管道类型) -> float:
    """
    参考《GB 50764 电厂动力管道设计规范》表格C.0.2

    :param 管道类型:
    :return: 返回各类管子的等值粗糙度，单位为mm
    """
    epsilon = 0.2591
    if 管道类型 == '冷拔钢管':
        epsilon = 0.0015
    elif 管道类型 == "普通钢管/熟铁管":
        epsilon = 0.0457
    elif 管道类型 == "涂沥青铸铁管":
        epsilon = 0.1220
    elif 管道类型 == "镀锌铸铁管":
        epsilon = 0.1524
    elif 管道类型 == "其他":
        epsilon = None
    return epsilon
